home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Code Resources / icl8 LDEF 2.0 / Source / icl8 LDEF.cpp next >
Text File  |  1995-11-14  |  12KB  |  396 lines

  1. /*
  2.         Hiep's Special LDEF
  3.         Written by: Hiep Dam
  4.         Date: Long time ago (Dec 93?)
  5.         Public domain.
  6.         
  7.         Previous incarnation as a pict list def, now a simple icon list def. Well,
  8.         not so simple. Each cell should contain the IconListData data; this list
  9.         def depends on each cell having at least this structure (you can extend it
  10.         if you want).
  11.  
  12.         The IconListData structure basically notes how to hilite and frame the
  13.         cell (thus, each cell could be framed and/or hilited differently, though
  14.         this is NOT recommended!). It also contains the "icl8" rsrc id of the icon
  15.         you want to use. If you frame the cell, make sure you specify the frameWidth.
  16.         Also, if you cells are not 32x32 or 16x16 (std icon sizes) then you should
  17.         specify the iconSize.
  18.         
  19.         Version History:
  20.             1.5 June 5 94: Changed from using PICTs to using icl8 icon families
  21.  
  22.             2.0 Nov 14 95: Added ability to draw name as well, updated API and
  23.                 drawing, selecting code. Pretty much complete overhaul.
  24.                 Thanks to Steven Falkenburg & Norman Franke, whose simpler icon
  25.                 LDEF source code structure made simplizing my code much easier.
  26. */
  27.  
  28. // ---------------------------------------------------------------------------
  29.  
  30. #include <Icons.h>
  31. #include "icl8 LDEF.h"
  32.  
  33. enum {
  34.     kIconNameHeight = 10
  35. };
  36.  
  37. // Used for kSelectbyFramingSpecial
  38. enum {
  39.     kFrameHiliteRed = 39321, kFrameHiliteGreen = 52428, kFrameHiliteBlue = 65535,
  40.     kFrameTingeRed = 26214, kFrameTingeGreen = 26214, kFrameTingeBlue = 39321,
  41.     kFrameBodyRed = 48059, kFrameBodyGreen = 48059, kFrameBodyBlue = 48059,
  42.     kBlack = 0
  43. };
  44.  
  45. // ---------------------------------------------------------------------------
  46.  
  47. static void CenterRect(Rect *innerRect, const Rect *outerRect);
  48.  
  49. static void GetIconDestRect(
  50.     const IconListDataPtr    theIcon,
  51.     const Rect                *cellRect,
  52.     Rect                    *destRect);
  53.  
  54. static void PlotIconName(
  55.     GrafPtr        ownerPort,
  56.     const IconListDataPtr theIcon,
  57.     const Rect    *iconRect,
  58.     const Rect    *cellRect,
  59.     Rect        *iconNameRect);
  60.  
  61. void DrawCell(
  62.     ListHandle    listH,
  63.     const Rect    *cellR,
  64.     Cell        theCell,
  65.     short        dataLen,
  66.     Boolean        select);
  67.  
  68. // ---------------------------------------------------------------------------
  69.  
  70. void CenterRect(Rect *innerRect, const Rect *outerRect) {
  71.     short outerRectWidth    = outerRect->right    - outerRect->left;
  72.     short outerRectHeight    = outerRect->bottom    - outerRect->top;
  73.     short innerRectWidth    = innerRect->right    - innerRect->left;
  74.     short innerRectHeight    = innerRect->bottom    - innerRect->top;
  75.     short hDiff                = (outerRectWidth - innerRectWidth) / 2;
  76.     short vDiff                = (outerRectHeight - innerRectHeight) / 2;
  77.     innerRect->left        = outerRect->left + hDiff;
  78.     innerRect->right    = innerRect->left + innerRectWidth;
  79.     innerRect->top        = outerRect->top + vDiff;
  80.     innerRect->bottom    = innerRect->top + innerRectHeight;
  81. } // END CenterRect
  82.  
  83. // ---------------------------------------------------------------------------
  84. // ---------------------------------------------------------------------------
  85.  
  86. /*
  87.     Determine destination area to draw icon in (centered inside the cell rect).
  88.     If the icon specifies to draw the name as well, the dest area is moved up
  89.     a bit to accomodate the name.
  90. */
  91. void GetIconDestRect(
  92.     const IconListDataPtr    theIcon,
  93.     const Rect                *cellRect,
  94.     Rect                    *destRect) {
  95.  
  96.     short cellWidth = cellRect->right - cellRect->left;
  97.     short cellHeight = cellRect->bottom - cellRect->top;
  98.     short whatIconSize;
  99.  
  100.     if (theIcon->iconSize != kIconBasedOnCellSize)
  101.         whatIconSize = theIcon->iconSize;
  102.     else if ((cellWidth > kIcon32Size) && (cellHeight > kIcon32Size))
  103.         whatIconSize = kIcon32Size;
  104.     else
  105.         whatIconSize = kIcon16Size;
  106.     
  107.     switch(whatIconSize) {
  108.         case kIcon32Size:
  109.             // Explicitly use 32 pixel size
  110.             SetRect(destRect, 0, 0, kIcon32Size, kIcon32Size);
  111.             // Accomodate space for name
  112.             if (theIcon->drawName)
  113.                 destRect->bottom += kIconNameHeight;
  114.             CenterRect(destRect, cellRect);
  115.         break;
  116.  
  117.         case kIcon16Size:
  118.             // Explicitly use 16 pixel size
  119.             SetRect(destRect, 0, 0, kIcon16Size, kIcon16Size);
  120.             if (theIcon->drawName)
  121.                 destRect->bottom += kIconNameHeight;
  122.             CenterRect(destRect, cellRect);
  123.         break;
  124.     }
  125.     
  126.     if (theIcon->drawName) {
  127.         destRect->bottom -= kIconNameHeight;
  128.     }
  129. } // END GetIconDestRect
  130.  
  131. // ---------------------------------------------------------------------------
  132.  
  133. /*
  134.     Draw the icon's name, based on the cell and icon rects. The name is
  135.     positioned centered and below the icon's rect.
  136.     
  137.     The adjusted rect of the name is passed out to <iconNameRect> for later
  138.     hiliting if needed. If there is no name, an empty rect is passed.
  139. */
  140. static void PlotIconName(
  141.     GrafPtr        ownerPort,
  142.     const IconListDataPtr theIcon,
  143.     const Rect    *iconRect,
  144.     const Rect    *cellRect,
  145.     Rect        *iconNameRect) {
  146.  
  147.     short saveFont, saveFontSize, saveFontFace;
  148.     
  149.     // Save current font, size, & face settings & set them to what we need to
  150.     saveFont = ownerPort->txFont;
  151.     saveFontSize = ownerPort->txSize;
  152.     saveFontFace = ownerPort->txFace;
  153.     TextFont(geneva);
  154.     TextSize(9);
  155.     TextFace(0);
  156.     
  157.     // Get icon name
  158.     Str255 iconName;
  159.     Handle iconHandle;
  160.     short iconID;
  161.     ResType iconType;
  162.     iconHandle = GetResource('icl8', theIcon->id);
  163.     GetResInfo(iconHandle, &iconID, &iconType, iconName);
  164.     ReleaseResource(iconHandle);
  165.     
  166.     // Center name
  167.     Rect nameRect;
  168.     if (iconName[0] == 0) {
  169.         SetRect(&nameRect, 0, 0, 0, 0);
  170.     }
  171.     else {
  172.         short nameWidth, cellWidth;
  173.         nameWidth = StringWidth(iconName);
  174.         cellWidth = cellRect->right - cellRect->left;
  175.         // Make sure name's width isn't longer than cell's; otherwise condense
  176.         if (nameWidth > cellWidth) {
  177.             TextFace(condense);
  178.             // Get width again (if still larger, clip it)
  179.             nameWidth = StringWidth(iconName);
  180.             if (nameWidth > cellWidth)
  181.                 nameWidth = cellWidth;
  182.         }
  183.         SetRect(&nameRect, 0, 0, nameWidth, kIconNameHeight);
  184.         CenterRect(&nameRect, cellRect);
  185.         nameRect.top = iconRect->bottom;
  186.         nameRect.bottom = nameRect.top + kIconNameHeight;
  187.         
  188.         // Draw it (finally...)
  189.         MoveTo(nameRect.left, nameRect.bottom);
  190.         DrawString(iconName);
  191.         
  192.         InsetRect(&nameRect, -3, 0);
  193.         nameRect.bottom += 2;
  194.     }
  195.  
  196.     TextFont(saveFont);
  197.     TextSize(saveFontSize);
  198.     TextFace(saveFontFace);
  199.     
  200.     *iconNameRect = nameRect;
  201. } // END PlotIconName
  202.  
  203. // ---------------------------------------------------------------------------
  204.  
  205. void DrawCell(
  206.     ListHandle    listH,
  207.     const Rect    *cellR,
  208.     Cell        theCell,
  209.     short        dataLen,
  210.     Boolean        select) {
  211.  
  212.     GrafPtr        savePort;
  213.     PenState    savePenState;
  214.     OSErr        myErr;
  215.     IconListData theIcon;
  216.     Rect        destRect;
  217.     Rect        iconNameRect;
  218.     RgnHandle    saveClip;
  219.  
  220.     GetPort(&savePort);
  221.     SetPort((**listH).port);
  222.     saveClip = NewRgn();
  223.     GetClip(saveClip);
  224.     ClipRect(cellR);                // Set clip region to cell rectangle, so no drawing outside cell
  225.     GetPenState(&savePenState);
  226.     PenNormal();
  227.  
  228.     dataLen = sizeof(IconListData);    // Only get enough stuff for our own purposes
  229.     LGetCell(&theIcon, &dataLen, theCell, listH);
  230.  
  231.     // --------------------------------------------------
  232.     // STEP 1: Draw cell
  233.     // --------------------------------------------------
  234.     EraseRect(cellR);
  235.     GetIconDestRect(&theIcon, cellR, &destRect);
  236.     // Here's the actual call that'll do the work for us. Note that myErr is
  237.     // ignored by this LDEF.
  238.     myErr = PlotIconID(&destRect, atNone, ttNone, theIcon.id);
  239.     if (theIcon.drawName)
  240.         PlotIconName((**listH).port, &theIcon, &destRect, cellR, &iconNameRect);
  241.  
  242.     // --------------------------------------------------
  243.     // STEP 2: Hilite cell and name accordingly (if need be)
  244.     // --------------------------------------------------
  245.     if (select) {
  246.         switch(theIcon.selType) {
  247.             case kSelectByInvertBW:
  248.             case kSelectByInvertHilite:
  249.                 if (theIcon.selType == kSelectByInvertHilite)
  250.                     LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
  251.                 InvertRect(cellR);
  252.             break;
  253.             
  254.             case kSelectByDarkenIcon:
  255.                 myErr = PlotIconID(&destRect, atNone, ttSelected, theIcon.id);
  256.                 // Hilite name
  257.                 if (theIcon.drawName) {
  258.                     LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
  259.                     InvertRect(&iconNameRect);
  260.                 }
  261.             break;
  262.  
  263.             case kSelectByFramingBW:
  264.                 // Frame cell by using a black border. Standard.
  265.                 ForeColor(blackColor);
  266.                 PenSize(theIcon.frameWidth, theIcon.frameWidth);
  267.                 FrameRect(cellR);
  268.             break;
  269.     
  270.             case kSelectbyFramingHilite:
  271.                 // Frame the cell by using the hilite color the user chose in the
  272.                 // General control panel. Note that this will work on a black and
  273.                 // white mac, too
  274.                 LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
  275.                 PenSize(theIcon.frameWidth, theIcon.frameWidth);
  276.                 PenMode(srcXor);
  277.                 FrameRect(cellR);
  278.             break;
  279.     
  280.             case kSelectByFramingSpecial:
  281.                 // Use Special: frame by drawing a special, funky-looking frame
  282.                 // that is copied after how the frame of a movable modal dialog looks.
  283.                 // Everything is hard coded into this LDEF. You can change this if you
  284.                 // wish. Note that it is up to the calling program to check if
  285.                 // it's running on a Color QuickDraw mac. This code does not check
  286.                 // whatsoever, so calling kUseSpecial on a black and white Mac will
  287.                 // result in a crash.
  288.                 
  289.                 RGBColor frameHilite, frameTinge, frameBody, frameBlack, foreSave;
  290.                 Rect frameRect = *cellR;
  291.                 
  292.                 frameBlack.red = frameBlack.green = frameBlack.blue = kBlack;
  293.                 frameHilite.red = kFrameHiliteRed;
  294.                 frameHilite.green = kFrameHiliteGreen;
  295.                 frameHilite.blue = kFrameHiliteBlue;
  296.                 frameTinge.red = kFrameTingeRed;
  297.                 frameTinge.green = kFrameTingeGreen;
  298.                 frameTinge.blue = kFrameTingeBlue;
  299.                 frameBody.red = kFrameBodyRed;
  300.                 frameBody.green = kFrameBodyGreen;
  301.                 frameBody.blue = kFrameBodyBlue;
  302.     
  303.                 GetForeColor(&foreSave);
  304.                 
  305.                 // Step 1: Draw outer black frame
  306.                 RGBForeColor(&frameBlack);
  307.                 FrameRect(&frameRect);
  308.  
  309.                 // Step 2: Draw outer upper left hilite
  310.                 RGBForeColor(&frameHilite);
  311.                 InsetRect(&frameRect, 1, 1); frameRect.right--; frameRect.bottom--;
  312.                 // Top edge
  313.                 MoveTo(frameRect.left, frameRect.top);
  314.                 LineTo(frameRect.right - 1, frameRect.top);
  315.                 // Left edge
  316.                 MoveTo(frameRect.left, frameRect.top);
  317.                 LineTo(frameRect.left, frameRect.bottom - 1);
  318.                 
  319.                 // Step 3: Draw outer lower right tinge
  320.                 RGBForeColor(&frameTinge);
  321.                 // Right edge
  322.                 MoveTo(frameRect.right, frameRect.bottom);
  323.                 LineTo(frameRect.right, frameRect.top);
  324.                 // Bottom edge
  325.                 MoveTo(frameRect.right, frameRect.bottom);
  326.                 LineTo(frameRect.left, frameRect.bottom);
  327.                 
  328.                 // Step 4: Draw inner body frame
  329.                 RGBForeColor(&frameBody);
  330.                 InsetRect(&frameRect, 1, 1); frameRect.right++; frameRect.bottom++;
  331.                 FrameRect(&frameRect);
  332.                 
  333.                 // Step 5: Draw inner upper left tinge
  334.                 RGBForeColor(&frameTinge);
  335.                 InsetRect(&frameRect, 1, 1); frameRect.right--; frameRect.bottom--;
  336.                 // Top edge
  337.                 MoveTo(frameRect.left, frameRect.top);
  338.                 LineTo(frameRect.right, frameRect.top);
  339.                 // Left edge
  340.                 MoveTo(frameRect.left, frameRect.top);
  341.                 LineTo(frameRect.left, frameRect.bottom);
  342.                 
  343.                 // Step 6: Draw inner lower right hilite
  344.                 RGBForeColor(&frameHilite);
  345.                 // Right edge
  346.                 MoveTo(frameRect.right, frameRect.bottom);
  347.                 LineTo(frameRect.right, frameRect.top - 1);
  348.                 // Bottom edge
  349.                 MoveTo(frameRect.right, frameRect.bottom);
  350.                 LineTo(frameRect.left - 1, frameRect.bottom);
  351.                 
  352.                 // Step 7: Draw inner black frame
  353.                 RGBForeColor(&frameBlack);
  354.                 InsetRect(&frameRect, 1, 1); frameRect.right++; frameRect.bottom++;
  355.                 FrameRect(&frameRect);
  356.  
  357.                 RGBForeColor(&foreSave);
  358.  
  359.                 // Uncomment if you want this method to hilite the icon name as well
  360.                 /*
  361.                 if (theIcon.drawName) {
  362.                     LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
  363.                     InvertRect(&iconNameRect);
  364.                 }
  365.                 */
  366.             break;
  367.         } // END switch
  368.     }
  369.  
  370.     SetClip(saveClip);
  371.     SetPenState(&savePenState);
  372.     SetPort(savePort);
  373. } // END DrawCell
  374.  
  375. // ---------------------------------------------------------------------------
  376.  
  377. #ifdef powerc
  378. ProcInfoType __procinfo = uppListDefProcInfo;
  379. #endif
  380.  
  381. pascal void main(short lMsg, Boolean lSelect, Rect *lRect, Cell lCell, short dataOffset,
  382.                 short dataLen, ListHandle theList) {
  383.     switch(lMsg) {
  384.         case lDrawMsg:
  385.         case lHiliteMsg:
  386.             DrawCell(theList, lRect, lCell, dataLen, lSelect);
  387.         break;
  388.         
  389.         default:
  390.         break;
  391.     } // END switch
  392. } // END main entry point
  393.  
  394.  
  395. // ---------------------------------------------------------------------------
  396. // END icl8 LDEF.cpp